import hashlib
import subprocess as sub

from django.urls import reverse
from django.shortcuts import render
from django.http import (HttpResponseNotFound, Http404,
                         HttpResponse, HttpResponseRedirect)
from django.core.exceptions import RequestDataTooBig, PermissionDenied
from django.views.decorators import http
from django.shortcuts import get_object_or_404, get_list_or_404
from django.views.generic import ListView, DetailView

from .models import Book, User
from .forms import LoginForm, SignupForm


def index(request):
    books = get_list_or_404(Book)
    context = {'data': books, 'title': 'Index 1', 'total': 1}
    return render(request, 'app1/index.html', context=context)


class BookListView(ListView):
    context_object_name = 'data'
    template_name = 'app1/index.html'

    def get_context_data(self, **kwargs):
        context = ListView.get_context_data(self, **kwargs)
        context['total'] = 1
        return context


def detail(request, pk):
    book = get_object_or_404(Book, pk=pk)
    return render(request, 'app1/detail.html', context=dict(book=book))


class BookDetailView(DetailView):

    def get_object(self):
        book = Book.objects.get(pk=self.kwargs['id'])
        return book


def e(request, code):
    code = int(code)
    if code == 400:
        raise RequestDataTooBig()
    elif code == 403:
        raise PermissionDenied()
    elif code == 404:
        raise Http404()
    else:
        raise Exception()


def online_user_list(request):
    out = sub.getoutput('who')
    lines = out.splitlines()
    info = [line.split() for line in lines]
    header = ('name', 'tty', 'date', 'time', 'source')
    info = [dict(zip(header, x)) for x in info]
    return render(request, 'app1/online_user_list.html', context={'users': info})


def online_user_detail(request, name):
    lines = open('/etc/passwd').read().splitlines()
    users = [line.split(':') for line in lines]
    user = [user for user in users if user[0] == name]
    if not user:
        return HttpResponseNotFound('user not found')

    user = user[0]
    header = ('name', 'password', 'uid', 'gid', 'comment', 'home', 'shell')
    user = dict(zip(header, user))

    return render(request, 'app1/online_user_detail.html', context={'user': user})


def login(request):
    if request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():
            # 表单通过了校验，可以继续
            name = form.cleaned_data['name']
            password = form.cleaned_data['password']
            encrypted_password = sha1sum(password)
            if not User.objects.filter(name=name,
                    password=encrypted_password).count():
                print('login failed')
            else:
                print('login success')
        else:
            # 表单没有通过校验
            ...
    else:
        form = LoginForm()
    return render(request, 'app1/login.html', context={'form': form, 'title': 'Login'})


def signup(request):
    if request.method == 'POST':
        form = SignupForm(request.POST)
        if form.is_valid():
            # 表单通过了校验，可以继续
            name = form.cleaned_data['name']
            password = form.cleaned_data['password']
            encrypted_password = sha1sum(password)
            if User.objects.filter(name=name).count():
                print('user exists')
            else:
                # 用户不存在，可以继续
                User.objects.create(name=name, password=encrypted_password)
                login_url = reverse('app1:login')
                return HttpResponseRedirect(redirect_to=login_url)
        else:
            # 表单没有通过校验
            ...
    else:
        form = SignupForm()
    return render(request, 'app1/signup.html', context={'form': form, 'title': 'Sign up'})


def sha1sum(text):
    h = hashlib.sha1(text.encode())
    return h.hexdigest()
